package com.jcn.seckill.rabbitmq;

import java.util.HashMap;
import java.util.Map;

import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.HeadersExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//定义配置类，可替换xml配置文件
@Configuration
//配置bean
public class MQConfig {
	
	public static final String MIAOSHA_QUEUE = "miaosha.queue";
	public static final String QUEUE = "queue";
	public static final String TOPIC_QUEUE1 = "topic.queue1";
	public static final String TOPIC_QUEUE2 = "topic.queue2";
	public static final String HEADER_QUEUE = "header.queue";
	public static final String TOPIC_EXCHANGE = "topicExchage";
	public static final String FANOUT_EXCHANGE = "fanoutxchage";
	public static final String HEADERS_EXCHANGE = "headersExchage";
	
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
    public Queue miaoShaQueue() {
    	return new Queue(MIAOSHA_QUEUE,true);
    }
	
	/**
	 * Direct模式 交换机Exchange
	 * */
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	public Queue queue() {
		return new Queue(QUEUE, true);
	}
	
	/**
	 * Topic模式 交换机Exchange
	 * */
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	public Queue topicQueue1() {
		return new Queue(TOPIC_QUEUE1, true);
	}
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	public Queue topicQueue2() {
		return new Queue(TOPIC_QUEUE2, true);
	}
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	//1.先将消息 放入exchange里
	//2.接着exchange将消息放入Queue中
	public TopicExchange topicExchage(){
		return new TopicExchange(TOPIC_EXCHANGE);
	}
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	//绑定到topicQueue1上
	public Binding topicBinding1() {
		return BindingBuilder.bind(topicQueue1()).to(topicExchage()).with("topic.key1");
	}
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	//绑定到topicQueue2上
	public Binding topicBinding2() {
		return BindingBuilder.bind(topicQueue2()).to(topicExchage()).with("topic.#");
	}
	/**
	 * Fanout模式 交换机Exchange
	 * */
	@Bean
	public FanoutExchange fanoutExchage(){
		return new FanoutExchange(FANOUT_EXCHANGE);
	}
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	public Binding FanoutBinding1() {
		return BindingBuilder.bind(topicQueue1()).to(fanoutExchage());
	}
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	public Binding FanoutBinding2() {
		return BindingBuilder.bind(topicQueue2()).to(fanoutExchage());
	}
	/**
	 * Header模式 交换机Exchange
	 * */
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	public HeadersExchange headersExchage(){
		return new HeadersExchange(HEADERS_EXCHANGE);
	}
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	public Queue headerQueue1() {
		return new Queue(HEADER_QUEUE, true);
	}
	/**
	 * @Bean注解用于告诉方法，产生一个Bean对象，
	 * 然后这个Bean对象交给Spring管理。产生这个Bean对象的方法Spring只会调用一次，
	 * 随后这个Spring将会将这个Bean对象放在自己的IOC容器中。
	 * */
	@Bean
	//1.首先有一个队列和交换机，再进行绑定，绑定需要指定header
	//2.发送需要原始信息+头部信息
	//3.接收找到queue接收出来
	public Binding headerBinding() {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("header1", "value1");
		map.put("header2", "value2");
		//当message满足有这个header部分,header部分要满足上面两个key,value，才能在headerQueue1中放入东西
		return BindingBuilder.bind(headerQueue1()).to(headersExchage()).whereAll(map).match();
	}
	
	
}
